package config

import (
	"fmt"
	"os"
	"time"

	"github.com/sirupsen/logrus"

	"github.com/spf13/viper"
)

type Config struct {
	Name               string        `mapstructure:"name"`
	Version            string        `mapstructure:"version"`
	Banner             string        `mapstructure:"banner"`
	Protocol           string        `mapstructure:"protocol"`
	Address            string        `mapstructure:"address"`
	Port               uint32        `mapstructure:"port"`
	ControlPort        uint32        `mapstructure:"ctlserv-port"`
	ConnReadTimeout    time.Duration `mapstructure:"conn-read-timeout"`     //连接读取超时时间
	ConnWriteTimeout   time.Duration `mapstructure:"conn-write-timeout"`    //连接写入超时时间
	ConnReadBufferSize int           `mapstructure:"conn-read-buffer-size"` //连接读取缓冲区大小
	MaxConnections     uint64        `mapstructure:"max-connections"`       //服务器允许的最大同时连接数
	Databases          []Database    `mapstructure:"databases"`
	Log                Log           `mapstructure:"log"`
	DataDirectory      string        `mapstructure:"data-directory"`
	Cluster            Cluster       `mapstructure:"cluster"`
}

type Database struct {
	Name      string   `mapstructure:"name"`
	Type      string   `mapstructure:"type"`
	Comment   string   `mapstructure:"comment"`
	Endpoints []string `mapstructure:"endpoints"`
	User      string   `mapstructure:"user"`
	Password  string   `mapstructure:"pwd"`
}

type Log struct {
	Level         string        `mapstructure:"level"`
	Path          string        `mapstructure:"path"`
	RotationTime  time.Duration `mapstructure:"rotation-time"`  //日志文件轮换间隔（单位:小时）
	RetentionTime time.Duration `mapstructure:"retention-time"` //日志文件保留时间（单位:小时）
}

type Cluster struct {
	Port    uint32   `mapstructure:"port"`
	Members []string `mapstructure:"members"`
}

const (
	ConfigName = "conf"
	ConfigPath = "."
	ConfigType = "yaml"

	banner_bulbhead = `
 ____    __   ____   __      ____  ____  _____  _  _  ____  ____ 
(  _ \  /__\ (_  _) /__\    (  _ \(  _ \(  _  )( )/ )( ___)(  _ \ 
 )(_) )/(__)\  )(  /(__)\    ) _ < )   / )(_)(  )  (  )__)  )   / 
(____/(__)(__)(__)(__)(__)  (____/(_)\_)(_____)(_)\_)(____)(_)\_) 
	`
)

var defaultConf = Config{
	Name:           "Databroker server",
	Version:        "1.0.0",
	Banner:         banner_bulbhead,
	Protocol:       "tcp",
	Address:        "127.0.0.1",
	Port:           3309,
	ControlPort:    8143,
	MaxConnections: 200,
	Log: Log{
		Level:         "INFO",
		Path:          "./",
		RotationTime:  24,
		RetentionTime: 7 * 24,
	},
	DataDirectory: "./",
	Cluster: Cluster{
		Port: 8385,
	},
}

var globalConf = defaultConf

func InitConfig() {
	HOME := os.Getenv("DBRS_HOME") //获取环境变量值
	viper.SetConfigName(ConfigName)
	viper.AddConfigPath(ConfigPath)
	viper.AddConfigPath(HOME)
	viper.SetConfigType(ConfigType)
	if err := viper.ReadInConfig(); err == nil {
		err = viper.Unmarshal(&globalConf)
		if err != nil {
			panic(fmt.Errorf("Fatal error when reading %s config, unable to decode into struct, %v", ConfigName, err))
		}
	}

	if len(GetConfig().Databases) < 1 {
		logrus.Fatalf("Database not found, please check the configuration file.")
	}
}

func GetConfig() *Config {
	return &globalConf
}
